package com.superb.system.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.superb.common.core.annotation.SuperbDataScope;
import com.superb.common.core.annotation.SuperbRestMapping;
import com.superb.common.core.model.Result;
import com.superb.common.database.entity.BaseEntity;
import com.superb.common.database.vo.BatchId;
import com.superb.common.utils.StringUtils;
import com.superb.system.api.dto.Options;
import com.superb.system.api.entity.*;
import com.superb.system.api.vo.Distribution;
import com.superb.system.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.List;

/**
 * @Author: ajie
 * @CreateTime: 2024-07-19 08:41
 */
@SuperbDataScope
@SuperbRestMapping("tenantConfig")
@SaCheckPermission("system:tenant:config")
@ApiSupport(author = "阿杰：ajie20999@163.com", order = 8)
@Tag(name = "租户系统配置管理", description = "权限：system:tenant:config")
public class TenantConfigController {

    @Resource
    private SystemPermissionService permissionService;
    @Resource
    private SystemTenantService tenantService;
    @Resource
    private SystemRoleService roleService;
    @Resource
    private SystemUserService userService;
    @Resource
    private UserDataScopeService userDataScopeService;
    @Resource
    private SystemOrganizationService organizationService;

    @GetMapping("menu/{tenantId}")
    @Operation(summary = "菜单列表", parameters = {
            @Parameter(name = "type", description = "菜单类型", required = true, in = ParameterIn.PATH),
            @Parameter(name = "tenantId", description = "租户id", required = true, in = ParameterIn.PATH),
    })
    public Result<List<SystemPermission>> menuQuery(@PathVariable String tenantId) {
        LambdaQueryWrapper<SystemPermission> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SystemPermission::getTenantId, tenantId);
        // 查询第一级菜单
        lqw.eq(SystemPermission::getMenuType, 0);
        List<SystemPermission> list = permissionService.list(lqw);
        permissionService.buildTree(list);
        return Result.success(list);
    }

    @GetMapping("menu/delete/{id}")
    @ApiOperationSupport(order = 2)
    @Operation(summary = "根据id彻底删除")
    public Result<Boolean> delete(@PathVariable String id) {
        if (permissionService.removeById(id)) {
            return Result.success();
        }
        return Result.error();
    }

    @PostMapping("menu/synchronization/{tenantId}")
    @ApiOperationSupport(order = 3)
    @Operation(summary = "根据id集合同步菜单", description = "同步会将子菜单和权限同步", parameters = {
            @Parameter(name = "tenantId", description = "租户id", required = true, in = ParameterIn.PATH),
    })
    public Result<Boolean> synchronization(@RequestBody @Validated BatchId batchId, @PathVariable String tenantId) {
        if (permissionService.synchronization(batchId, tenantId)) {
            return Result.success();
        }
        return Result.error();
    }

    @GetMapping("tenantOptions")
    @ApiOperationSupport(order = 4)
    @Operation(summary = "租户下拉列表")
    public Result<List<Options>> tenantOptions() {
        QueryWrapper<SystemTenant> lqw = new QueryWrapper<>();
        lqw.select("tenant_key AS `value`", "name AS label");
        List<Options> list = JSONArray.from(tenantService.listMaps(lqw)).toJavaList(Options.class);
        return Result.success(list);
    }

    @ApiOperationSupport(order = 5)
    @GetMapping("menuOptions/{tenantId}")
    @Operation(summary = "租户一级菜单列表", parameters = {
            @Parameter(name = "tenantId", description = "租户id", required = true, in = ParameterIn.PATH),
    })
    public Result<List<Options>> menuOptions(@PathVariable String tenantId) {
        QueryWrapper<SystemPermission> lqw = new QueryWrapper<>();
        lqw.select("id AS `value`", "name AS label");
        lqw.lambda().eq(SystemPermission::getMenuType, 0).eq(SystemPermission::getTenantId, tenantId);
        List<Options> list = JSONArray.from(permissionService.listMaps(lqw)).toJavaList(Options.class);
        return Result.success(list);
    }


    @GetMapping("role/{tenantId}")
    @Operation(summary = "角色列表", parameters = {
            @Parameter(name = "tenantId", description = "租户id", required = true, in = ParameterIn.PATH),
    })
    public Result<List<SystemRole>> roleQuery(@PathVariable String tenantId) {
        LambdaQueryWrapper<SystemRole> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SystemRole::getTenantId, tenantId);
        lqw.eq(SystemRole::getType, 0);
        List<SystemRole> list = roleService.list(lqw);
        return Result.success(list);
    }

    @PostMapping("roleAction")
    @Operation(summary = "角色操作")
    public Result<Boolean> roleAction(@RequestBody SystemRole role) {
        if (StringUtils.isNotBlank(role.getId())) {
            // 删除权限
            permissionService.deletePermsByRoleId(role.getId());
        }
        if (roleService.saveOrUpdate(role)) {
            // 添加角色权限
            LambdaQueryWrapper<SystemPermission> lqw = new LambdaQueryWrapper<>();
            lqw.select(SystemPermission::getId, SystemPermission::getMenuType);
            lqw.eq(SystemPermission::getTenantId, role.getTenantId());
            List<SystemPermission> list = permissionService.list(lqw);
            List<String> permIds = list.stream().filter(i -> i.getMenuType() == 2).map(SystemPermission::getId).toList();
            List<String> menus = list.stream().filter(i -> i.getMenuType() == 0 || i.getMenuType() == 1).map(SystemPermission::getId).toList();
            Distribution distribution = new Distribution();
            distribution.setRoleId(role.getId());
            distribution.setMenuIds(menus);
            distribution.setPermissionIds(permIds);
            permissionService.distribution(distribution);
            return Result.success();
        }
        return Result.error();
    }

    @GetMapping("user/{tenantId}")
    @Operation(summary = "租户管理员列表")
    public Result<List<SystemUser>> userQuery(@PathVariable String tenantId) {
        LambdaQueryWrapper<SystemUser> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SystemUser::getSuperb, 1);
        lqw.eq(SystemUser::getTenantId, tenantId);
        return Result.success(userService.list(lqw));
    }


    @PostMapping("userAction")
    @Operation(summary = "租户管理员操作", description = "新增/修改租户管理员，会新增默认数据权限，管理员数据权限默认为本部门及子部门")
    public Result<Boolean> userAction(@RequestBody SystemUser user) {
        // 获取租户部门id
        Organization organization = organizationService.getOne(Wrappers.<Organization>lambdaQuery()
                .eq(BaseEntity::getTenantId, user.getTenantId()).eq(Organization::getParentCode, 1).last("LIMIT 1"));
        if (StringUtils.isNotBlank(user.getId())) {
            // 删除管理员数据权限
            userDataScopeService.remove(Wrappers.<UserDataScope>lambdaQuery().eq(UserDataScope::getUserId, user.getId()).eq(UserDataScope::getTenantId, user.getTenantId()));
        } else {
            user.setOrganId(organization.getId());
            user.setSuperb(1);
        }
        String salt = RandomStringUtils.random(10, "SuperbAjiez01654+/=*");
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        user.setPassword(encoder.encode(salt + "12345678"));
        user.setSalt(salt);
        if (userService.saveOrUpdate(user)) {
            UserDataScope userDataScope = new UserDataScope();
            userDataScope.setTenantId(user.getTenantId());
            userDataScope.setUserId(user.getId());
            userDataScope.setOrganId(organization.getId());
            userDataScope.setDataScopeType(3);
            userDataScope.setIsMain(1);
            userDataScope.setEnable(0);
            // 获得租户系统角色id
            List<String> roleIds = roleService.listObjs(Wrappers.<SystemRole>lambdaQuery()
                    .eq(SystemRole::getTenantId, user.getTenantId()).select(SystemRole::getId).eq(SystemRole::getType, 0), Object::toString);
            userDataScope.setRoleId(String.join(",", roleIds));
            // 保存数据权限
            userDataScopeService.save(userDataScope);
            return Result.success();
        }
        return Result.error();
    }
}
